/*
 * data_packet.h
 *
 *  Created on: 10.06.2013
 *      Author: SpirTanol
 */

#ifndef DATA_PACKET_H_
#define DATA_PACKET_H_

#include <vector>

class DataPacket
{
public:
	struct Part
	{
		void *oPtr;
		int oSize;
		int oAddr;

		Part(void *ptr, int size, int addr) : oPtr(ptr), oSize(size << 1), oAddr(addr) {}
	};

	DataPacket() {}
	virtual ~DataPacket() {}

	virtual DataPacket *clone() const = 0;

private:
	std::vector<Part> oParts;

public:
	inline int partCount() const { return int(oParts.size()); }
	inline const Part &part(int idx) const { return oParts[idx]; };

protected:
	inline void addPart(const Part &part) { oParts.push_back(part); }

};

template<typename T>
class TDataPacket : public DataPacket
{
	int oAddr;
	T oData;

public:
	TDataPacket(int addr) : oAddr(addr) { addPart(Part(&oData, sizeof(T) >> 1, oAddr)); }
	TDataPacket(const TDataPacket *packet) { TDataPacket(packet->oAddr); oData = packet->oData; }
	~TDataPacket() {}

	inline void setAddr(int addr) { oAddr = addr; }
	inline int addr() const { return oAddr; }

	inline void setData(const T& data) { oData = data; }
	inline const T &data() const { return oData; }

	inline TDataPacket *clone() const { return new TDataPacket(this); }

};

#endif /* DATA_PACKET_H_ */
